#define AUTODELETE_C
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//user head_itemer
#include <libmscommon/mscommon.h>
#include <libmscommon/msstring.h>
#include <libmscommon/mstime.h>
#include <libmscommon/mscjson.h>
#include <libmscommon/msmd.h>
#include <libmsprotocol/msprotocol.h>
#include <libmslog/mslog.h>
#include "msautodelete.h"

#define FLAG "AUTO_DELETE"

static ms_void msautodel_innerapi_show(AUTODELETEContext *pAdel_ctt)
{
	ms_s32 index = 0;	
	if(ms_moreThan(pAdel_ctt->headItem, pAdel_ctt->tailItem) ){
		for(index=pAdel_ctt->tailItem;index<pAdel_ctt->headItem;index++){
			ms_verbose("%03d.[%s]%s",index,pAdel_ctt->dbname,pAdel_ctt->listItem[index]);
		}
	}else if(ms_lessThan(pAdel_ctt->headItem, pAdel_ctt->tailItem) ){
		for(index=pAdel_ctt->tailItem;index<msde_maxnum_list;index++){
			ms_verbose("%03d.[%s]%s",index,pAdel_ctt->dbname,pAdel_ctt->listItem[index]);
		}
		for(index=0;index<pAdel_ctt->headItem;index++){
			ms_verbose("%03d.[%s]%s",index,pAdel_ctt->dbname,pAdel_ctt->listItem[index]);
		}
	}
}

static ms_s08 msautodel_innerapi_readDB(AUTODELETEContext *pAdel_ctt,char *dbname)
{
	//init  list
	ms_memset(pAdel_ctt->listItem, 0, sizeof(pAdel_ctt->listItem));
	pAdel_ctt->tailItem=0;
	pAdel_ctt->headItem=0;
	
	URLProtocol *hfile=(URLProtocol*)msptc_api_matchByPtcindex(msptc_file);
	char json_buf[40960]={0};
	URLContext json_ctt;
	ms_memset(&json_ctt,0,sizeof(URLContext));
	ms_strcpy(json_ctt.url,dbname);
	if(hfile->url_open(&json_ctt)<0){
		return -1;
	}
	hfile->url_read(&json_ctt,json_buf,sizeof(json_buf));
	hfile->url_close(&json_ctt);
	cJSON *root = cJSON_Parse(json_buf);
	if(!root) {
		ms_errRet(-1,"Get root faild");
	}
	cJSON *js_autoitem_num= cJSON_GetObjectItem(root, "autoitem_num");
	if(!js_autoitem_num) {
		ms_errRet(-1,"no %s","autoitem_num");
	}
	int autoitem_num=0;
	if(cJSON_Number== js_autoitem_num->type){
		autoitem_num=js_autoitem_num->valueint;
	}else{
		ms_errRet(-1,"Err \"autoitem_num\" type");
	}
	
	pAdel_ctt->headItem=autoitem_num;
	char autoitem_buf[32]={0};
	int autoitem_index=0;
	cJSON *js_autoitem=ms_null;
	for(autoitem_index=0;autoitem_index<autoitem_num;autoitem_index++){
		ms_sprintfs(autoitem_buf,"autoitem%03d",autoitem_index);
		js_autoitem= cJSON_GetObjectItem(root,autoitem_buf);
		if(!js_autoitem) {
			ms_errRet(-1,"no %s",autoitem_buf);
		}
		if(cJSON_String== js_autoitem->type){
			ms_strcpy(pAdel_ctt->listItem[autoitem_index],js_autoitem->valuestring);	
		}else{
			ms_errRet(-1,"Err %s type",autoitem_buf);
		}
	}
}
static ms_void msautodel_innerapi_writeDB(AUTODELETEContext *pAdel_ctt,char *dbname)
{
	int autoitem_num=0;
	if (pAdel_ctt->headItem > pAdel_ctt->tailItem){
		autoitem_num=pAdel_ctt->headItem-pAdel_ctt->tailItem;
	}else{
		autoitem_num=(pAdel_ctt->headItem+msde_maxnum_list)-pAdel_ctt->tailItem;
	}
	cJSON * json_root = cJSON_CreateObject();
	if(NULL == json_root){
		ms_errNoret("cJSON_CreateObject failed");
	}
	cJSON_AddNumberToObject(json_root, "autoitem_num", autoitem_num);
	int autoitem_index=0;
	char autoitem_buf[32]={0};
	
	unsigned int list_item_cur=0;
	for(autoitem_index=0;autoitem_index<autoitem_num;autoitem_index++){
		ms_sprintfs(autoitem_buf,"autoitem%03d",autoitem_index);
		list_item_cur=pAdel_ctt->tailItem+autoitem_index;
		if(list_item_cur==msde_maxnum_list){
			list_item_cur=0;
		}
		MSJSON_BUILD_STRING(json_root, autoitem_buf, pAdel_ctt->listItem[list_item_cur]);
	}	

	char * json_string = cJSON_Print(json_root);
	cJSON_Delete(json_root);
	if(NULL==json_string){
		ms_errNoret("cJSON_Print failed");
	}
	if(msmd_api_writeProtect(dbname,json_string,ms_buflen(json_string))<0){
		ms_error("Write %s failed",dbname);
	}
	ms_free(json_string);
}
static ms_u32 msautodel_innerapi_getListNum(AUTODELETEContext *pAdel_ctt)
{
	ms_u32 numList=0;
	if(ms_moreThan(pAdel_ctt->headItem, pAdel_ctt->tailItem) ){
		numList=pAdel_ctt->headItem-pAdel_ctt->tailItem;
	}else if(ms_lessThan(pAdel_ctt->headItem, pAdel_ctt->tailItem) ){
		numList=pAdel_ctt->headItem+(msde_maxnum_list-pAdel_ctt->tailItem);
	}
	return numList;
}

static ms_void msautodel_innerapi_rm(AUTODELETEContext *pAdel_ctt,ms_u32 time,ms_bool flag_dir)
{
	ms_u32 numList=msautodel_innerapi_getListNum(pAdel_ctt);
	while(ms_moreThan(numList, time) ){
		if(flag_dir){
			ms_byte rm_cmd[512]={0};
			ms_rmdir(rm_cmd, pAdel_ctt->listItem[pAdel_ctt->tailItem]);
			ms_verbose("rm_cmd:%s",rm_cmd);
		}else{
			ms_remove(pAdel_ctt->listItem[pAdel_ctt->tailItem]);
		}
		ms_memset(pAdel_ctt->listItem[pAdel_ctt->tailItem],0,256);
		pAdel_ctt->tailItem++;	
		numList=msautodel_innerapi_getListNum(pAdel_ctt);
	}
}
/*初始化pAdel_ctt，并将列表状态正常化*/
ms_void msautodel_api_dayInit(AUTODELETEContext *pAdel_ctt,ms_u32  timeDay,ms_string dumppath,ms_string dbname)
{
/*如果删除时间超过范围，则直接报错*/
	if(ms_moreThan(timeDay, msde_maxnum)){
		ms_errExit(1, "timeDay(%d)  is out of range(0~%d),exit",timeDay,msde_maxnum);
	}
/*初始化pAdel_ctt结构*/
	ms_memset(pAdel_ctt,0,sizeof(AUTODELETEContext));
	msautodel_innerapi_readDB(pAdel_ctt,dbname);
	pAdel_ctt->time=timeDay;
	ms_strcpy(pAdel_ctt->dumppath, dumppath);
	ms_strcpy(pAdel_ctt->dbname, dbname);
	
/*获取当天的目录，并将其加入列表*/
	ms_byte curdate_string[128]={0};
	mstime_api_curDate(mstime_fmt_date, curdate_string);
	char curdatapath_string[256]={0};
	#if defined(OS_WIN32)
		ms_sprintfs(curdatapath_string,"%s\\%s",pAdel_ctt->dumppath,curdate_string);	
	#else
		ms_sprintfs(curdatapath_string,"%s/%s",pAdel_ctt->dumppath,curdate_string);	
	#endif	
	//如果未加入列表，则进行记录
	if( (0<pAdel_ctt->headItem&&ms_strncmp_sneq( pAdel_ctt->listItem[(pAdel_ctt->headItem-1)],curdatapath_string))
		||0==pAdel_ctt->headItem){
		ms_strcpy(pAdel_ctt->listItem[pAdel_ctt->headItem],curdatapath_string);	
		pAdel_ctt->headItem+=1;
	}
	
/*删除超过天数的目标*/	
	msautodel_innerapi_rm(pAdel_ctt,(pAdel_ctt->time+1),ms_true);
		
/*打印列表*/		
	msautodel_innerapi_show( pAdel_ctt);
/*存储数据*/		
	msautodel_innerapi_writeDB(pAdel_ctt,pAdel_ctt->dbname);
}

/*维护列表状*/
ms_void msautodel_api_dayRun(AUTODELETEContext *pAdel_ctt)
{
/*获取当天的目录，并将其加入列表*/
	ms_byte curdate_string[128]={0};
	mstime_api_curDate(mstime_fmt_date, curdate_string);
	ms_debug("It is a new day[%s](head_item,tail_item:%d %d)",curdate_string,pAdel_ctt->headItem,pAdel_ctt->tailItem);
#if defined(OS_WIN32)
	ms_sprintfs(pAdel_ctt->listItem[pAdel_ctt->headItem],"%s\\%s",pAdel_ctt->dumppath,curdate_string);	
#else
	ms_sprintfs(pAdel_ctt->listItem[pAdel_ctt->headItem],"%s/%s",pAdel_ctt->dumppath,curdate_string);
#endif
	pAdel_ctt->headItem++;
	if(pAdel_ctt->headItem==msde_maxnum_list){
		pAdel_ctt->headItem=0;
	}
	if(pAdel_ctt->tailItem==msde_maxnum_list){
		pAdel_ctt->tailItem=0;
	}
/*删除超过天数的目标*/		
	msautodel_innerapi_rm(pAdel_ctt,(pAdel_ctt->time+1),ms_true);
/*打印列表*/		
	msautodel_innerapi_show( pAdel_ctt);
/*存储数据*/		
	msautodel_innerapi_writeDB(pAdel_ctt,pAdel_ctt->dbname);
}

ms_void msautodel_api_hourInit(AUTODELETEContext *pAdel_ctt,ms_u32  timeHour,ms_string dbname)
{
/*如果删除时间超过范围，则直接报错*/
	if(ms_moreThan(timeHour, msde_maxnum)){
		ms_errExit(1, "timeHour(%d)  is out of range(0~%d),exit", timeHour,msde_maxnum);
	}
/*初始化pAdel_ctt结构*/	
	ms_memset(pAdel_ctt,0,sizeof(AUTODELETEContext));
	msautodel_innerapi_readDB(pAdel_ctt,dbname);
	pAdel_ctt->time=timeHour;
	ms_strcpy(pAdel_ctt->dbname, dbname);
/*打印列表*/		
	msautodel_innerapi_show( pAdel_ctt);
}
ms_void msautodel_api_hourRun(AUTODELETEContext *pAdel_ctt,ms_string fileName)
{
/*将分片加入列表*/
	ms_strcpy(pAdel_ctt->listItem[pAdel_ctt->headItem],fileName);	
	pAdel_ctt->headItem++;
	if(pAdel_ctt->headItem==msde_maxnum_list){
		pAdel_ctt->headItem=0;
	}
	if(pAdel_ctt->tailItem==msde_maxnum_list){
		pAdel_ctt->tailItem=0;
	}	
/*删除超过时间的目标*/		
	msautodel_innerapi_rm(pAdel_ctt,(pAdel_ctt->time*2+1),ms_false);
/*打印列表*/		
	msautodel_innerapi_show( pAdel_ctt);	
/*存储数据*/		
	msautodel_innerapi_writeDB(pAdel_ctt,pAdel_ctt->dbname);
}

#undef AUTODELETE_C
